package com.fecean.aabbc.netty.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

/**
 ** ICE请求对象
 */
public class IceRequest extends BaseRequest {

    private static final long serialVersionUID = 7959105008684203553L;

    private transient Logger logger = LoggerFactory.getLogger(IceRequest.class);

    private String cmd;
    private String uuid;
    private String token;
    private String usbKey;
    private Map<String, List<String>> data = new HashMap<>();
    private transient JsonNode root = null;

    public IceRequest(String jsonString) {
        try {
            ObjectMapper rootMapper = new ObjectMapper();
            if (!StringUtils.isEmpty(jsonString)) {
                root = rootMapper.readTree(jsonString);
                this.cmd = root.get("cmd").textValue();
                JsonNode j = root.get("uuid");
                this.uuid = j != null ? j.textValue() : UUID.randomUUID().toString();

                JsonNode t = root.get("token");
                if (t != null) {
                    this.token = t.textValue();
                }

                if (token == null) {
                    token = UUID.randomUUID().toString();
                }

                JsonNode node = root.get("usb_key");
                if (node != null) {
                    this.usbKey = node.textValue();
                }

                JsonNode dataNode = root.get("data");
                if (dataNode != null) {
                    Iterator<String> it = dataNode.fieldNames();
                    while (it.hasNext()) {
                        String name = it.next();
                        JsonNode jn = dataNode.get(name);
                        if (jn.getNodeType() == JsonNodeType.ARRAY) {
                            ArrayNode an = (ArrayNode) jn;
                            List<String> list = new ArrayList<>();
                            Iterator<JsonNode> tmpIt = an.iterator();
                            while (tmpIt.hasNext()) {
                                JsonNode tmpJN = tmpIt.next();
                                if (tmpJN.isDouble() || tmpJN.isFloat()) {
                                    list.add(String.valueOf(tmpJN.doubleValue()));
                                } else if (tmpJN.isBigDecimal()) {
                                    list.add(String.valueOf(tmpJN.decimalValue()));
                                } else if (tmpJN.isInt() || tmpJN.isBigInteger()) {
                                    list.add(String.valueOf(tmpJN.asInt()));
                                } else {
                                    list.add(tmpJN.textValue());
                                }
                            }
                            data.put(name, list);
                        } else {
                            List<String> list = new ArrayList<>();
                            String str;
                            if (jn.booleanValue()) {
                                str = String.valueOf(jn.asBoolean());
                            } else if (jn.isDouble() || jn.isBigDecimal()) {
                                str = String.valueOf(jn.asDouble());
                            } else if (jn.isInt()) {
                                str = String.valueOf(jn.asInt());
                            } else if (jn.isLong()) {
                                str = String.valueOf(jn.asLong());
                            } else if (jn.isNull()) {
                                str = null;
                            } else {
                                str = jn.asText();
                            }
                            list.add(str);
                            data.put(name, list);
                        }
                    }

                }
            } else {
                throw new RuntimeException("参数json为空");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
    }

    /**
     * 取得请求JSON对象
     *
     * @return
     */
    public JsonNode getRequestJsonObject() {
        return this.root;
    }

    public String getCmd() {
        return cmd;
    }

    public String getUsbKey() {
        String key = data.get("usbkey") != null ? data.get("usbkey").get(0) : null;
        return usbKey != null ? usbKey : key;
    }

    public String getUuid() {
        return uuid;
    }

    public String getToken() {
        return this.token;
    }

    public String getStringTrim(String key) {
        String temp = getString(key);
        if (null != temp) {
            return temp.trim();
        }
        return null;
    }

    public String getStringTrimToEmpty(String key) {
        String temp = getString(key);
        if (null != temp) {
            return temp.trim();
        }
        return "";
    }

    public String getString(String key) {
        List<String> list = data.get(key);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    public String[] getString2(String key) {
        List<String> list = data.get(key);
        String tmpd;
        if (list != null && !list.isEmpty()) {
            tmpd = list.get(0);
            return ArrayUtils.toArray(tmpd);
        }
        return new String[0];
    }

    public List<String> getStringList(String key) {
        return data.get(key);
    }

    public Integer getInteger(String key) {
        String s = this.getString(key);
        if (!StringUtils.isEmpty(s)) {

            return Integer.valueOf(s);
        }
        return null;
    }

    public List<Integer> getIntegerList(String key) {
        List<String> list = data.get(key);
        List<Integer> result = null;
        if (list != null) {
            result = new ArrayList<>();
            Iterator<String> it = list.iterator();
            while (it.hasNext()) {
                String str = it.next();
                Integer n = null;
                if (!StringUtils.isEmpty(str)) {
                    n = Integer.valueOf(str);
                }
                result.add(n);
            }

        }
        return result;
    }

    public Long getLong(String key) {
        String s = this.getString(key);
        if (!StringUtils.isEmpty(s)) {
            return Long.valueOf(s);
        }
        return null;
    }

    public List<Long> getLongList(String key) {
        List<String> list = data.get(key);
        List<Long> result = null;
        if (list != null) {
            result = new ArrayList<>();
            Iterator<String> it = list.iterator();
            while (it.hasNext()) {
                String str = it.next();
                Long n = null;
                if (!StringUtils.isEmpty(str)) {
                    n = Long.valueOf(str);
                }
                result.add(n);
            }

        }
        return result;
    }

    public Double getDouble(String key) {
        String s = this.getString(key);
        if (!StringUtils.isEmpty(s)) {
            return Double.valueOf(s);
        }
        return null;
    }

    public List<Double> getDoubleList(String key) {
        List<String> list = data.get(key);
        List<Double> result = null;
        if (list != null) {
            result = new ArrayList<>();
            Iterator<String> it = list.iterator();
            while (it.hasNext()) {
                String str = it.next();
                Double n = null;
                if (!StringUtils.isEmpty(str)) {
                    n = Double.valueOf(str);
                }
                result.add(n);
            }

        }
        return result;
    }

    public Boolean getBoolean(String key) {
        String s = this.getString(key);
        if (!StringUtils.isEmpty(s)) {
            return Boolean.valueOf(s);
        }
        return Boolean.FALSE;
    }

    public List<Boolean> getBooleanList(String key) {
        List<String> list = data.get(key);
        List<Boolean> result = null;
        if (list != null) {
            result = new ArrayList<>();
            Iterator<String> it = list.iterator();
            while (it.hasNext()) {
                String str = it.next();
                Boolean n = null;
                if (!StringUtils.isEmpty(str)) {
                    n = Boolean.valueOf(str);
                }
                result.add(n);
            }

        }
        return result;
    }

    public Date getDate(String key, String pattern) {
        String s = this.getString(key);
        if (!StringUtils.isEmpty(s)) {
            return string2Date(s, pattern);
        }
        return null;
    }

    public Date getDate(String key) {
        return getDate(key, null);
    }

    public List<Date> getDateList(String key) {
        List<String> list = data.get(key);
        List<Date> result = null;
        if (list != null) {
            result = new ArrayList<>();
            Iterator<String> it = list.iterator();
            while (it.hasNext()) {
                String str = it.next();
                Date n = null;
                if (!StringUtils.isEmpty(str)) {
                    n = string2Date(str);
                }
                result.add(n);
            }

        }
        return result;
    }

    public Map<String, List<String>> getData() {
        return data;
    }

    @Override
    public String toString() {
        StringBuilder out = new StringBuilder();
        out.append("cmd=" + this.cmd + "\n");
        out.append("uuid=" + this.uuid + "\n");
        out.append("token=" + this.token + "\n");
        Iterator<Entry<String, List<String>>> it = data.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, List<String>> en = it.next();
            out.append(en.getKey() + "=" + en.getValue().toString() + "\n");
        }

        return out.toString();
    }

    private Date string2Date(String d) {
        return string2Date(d, null);
    }

    private Date string2Date(String d, String pattern) {
        if (StringUtils.isEmpty(d)) {
            return null;
        }

        DateFormat df;
        Date date;
        if (pattern == null) {
            pattern = "yyyy-MM-dd";
            if (d.length() > 10) {
                pattern += " HH:mm:ss";
            }
        }
        df = new SimpleDateFormat(pattern);
        try {
            date = df.parse(d);
        } catch (ParseException e) {
            throw new RuntimeException(e.getMessage());
        }
        return date;
    }
}
